﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Claims;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authorization;
using Elight.Infrastructure.Settings;
using Elight.WebApi.Models;
using Elight.Infrastructure.Extensions;
using Elight.Entity;
using Elight.WebApi.Responses;
using Elight.Service.Interfaces;

namespace Elight.WebApi.Controllers
{
    [Route("api/signin")]
    public class TokenController : BaseController
    {
        private readonly JwtSetting _jwtSettings;
        private readonly IUserSigninService _userSigninService;

        public TokenController(
            IOptions<AppSettings> appSettings,
            IUserSigninService userSigninService)
        {
            _jwtSettings = appSettings.Value.Jwt;
            _userSigninService = userSigninService;
        }

        [AllowAnonymous, HttpGet("signin")]
        public IActionResult Get([FromQuery]AuthRequest request)
        {
            //TODO:组装前端登陆认证请求基础数据。
            request.GrantType = GrantTypes.Password;
            request.UserName = "esofar";
            request.Password = "000000".Md5Encrypt(); 

            if (request.GrantType == GrantTypes.Password)
            {
                var isValid = _userSigninService.Validate(request.UserName, request.Password);

                if (isValid.Item1 != null)
                {
                    //认证成功，创建登陆签名。
                    var token = CreateToken(isValid.Item1, request.GrantType);
                    return Success(isValid.Item2, token);
                }
                else
                {
                    //认证失败，提示错误消息。
                    return Error(isValid.Item2);
                }
            }
            else if (request.GrantType == GrantTypes.RefreshToken)
            {
                return Error("刷新Token功能未实现...");
            }
            else
            {
                return BadRequest();
            }
        }

        private Token CreateToken(Sys_User user, string grantType)
        {
            var now = DateTime.UtcNow;

            var claims = new Claim[] {
                new Claim(JwtRegisteredClaimNames.Sub, grantType, ClaimValueTypes.Integer),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Iat, now.ToUniversalTime().ToString(), ClaimValueTypes.Integer64),
                new Claim("uid",user.Id.ToString(),ClaimValueTypes.Integer32),
                new Claim("uname",user.UserName)
             };

            var symmetricKeyAsBase64 = _jwtSettings.Secret;
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);

            var jwt = new JwtSecurityToken(
                issuer: _jwtSettings.Issuer,
                audience: _jwtSettings.Audience,
                claims: claims,
                notBefore: now,
                expires: now.Add(TimeSpan.FromMinutes(_jwtSettings.Expiration)),
                signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256));

            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

            var result = new Token
            {
                TokenType = "Bearer",
                AaccessToken = encodedJwt,
                ExpiresIn = (int)TimeSpan.FromMinutes(_jwtSettings.Expiration).TotalSeconds,
                RefreshToken = "fdb8fdbecf1d03ce5e6125c067733c0d51de209c".Base64Encrypt()
            };

            return result;
        }

    }

}
